<?php
namespace app\http\middleware;
use think\Controller;
use base\BaseMethod;

/**
* token验证中间件
* Class AuthTokenMiddleware
* @package app\http\middleware
*/
class AuthTokenApp extends Controller
{
	public  		 	 $errorInfo;   			//错误信息
	public  		 	 $errorData=[];   		//错误数据
	public  		 	 $code=-1;   				//错误code
	public  		 	 $userInfo; 				//当前登录账号信息
	public  		 	 $shopInfo; 				//当前登录账号的店铺信息
	public  		 	 $userAction; 			//当前用户所拥有的授权
	protected  	 $isLogin; 					//是否登录
	protected  	 $isAllowPath; 			//白名单接口
	protected  	 $activeUrl; 				//当前接口地址
	
	//自执行中间件方法
   	public function handle($request, \Closure $next){
		
		//当前接口地址
		$this->activeUrl = strtolower( get_active_url() );

		//检测所有请求参数是否有sql注入的风险
		if( $this->is_exist_sql_inject() ){
			return BaseMethod::ReError("监听到存在SQL注入的风险</br>请调整后重新操作！",-2);
		}
		
		//获取当前接口描述信息
		$desc = get_method_desc();
		
		//效验请求
		$method = strtolower($desc['method']);
		if( $method !='all' && strtolower($request->method()) != $method){
			return BaseMethod::ReError("不允许".strtolower($request->method()).'请求！');
		}
		
		//效验接口登录情况
		if ( !$this->isLogin()  && $desc['is_need_login'] !='false' ){
			return BaseMethod::ReError($this->errorInfo,$this->code,$this->errorData);
		}
		
		//效验是否需要注册vip信息
		if($desc['is_vip']=='true' && !$this->userInfo->vip_info){
			return BaseMethod::ReError('请先注册会员！',-2);
		}
		
		//如果是商家端，效验当前用户是否可操作
		strstr($this->activeUrl,"v3") && $this->is_shop();
		if( strstr($this->activeUrl,"v2") && !$this->is_shop() && $desc['is_need_login'] !='false' ){
			return BaseMethod::ReError('您不是商家或店员,禁止该操作！'); 
		}
		
		//用户信息
		$request->userInfo = $this->userInfo;
		$request->userId = $this->userInfo['id'];
		$request->shopId = request()->header('x-shop',$this->userInfo['shop_id']);
		if($request->shopId === ""){
			$request->shopId = $this->userInfo['shop_id'];
		}
		
        return $next($request);
    }
	
	/**
     * 验证登录
     * @return boolean
     */
    public function isLogin()
    {
		$accessToken = request()->header('authorization');
		if ( empty( $accessToken ) ) {
			$this->errorInfo = '找不到Token！';
			$this->code = -10;
			return false;
        }
		
		if( strstr($this->activeUrl,"v2") ){
			$result = action('app/soft/auth2/getUserInfo',$accessToken); 
			$refreshToken = '/app/soft/auth2/refreshToken';
		}else{
			$result = action('app/soft/auth/getUserInfo',$accessToken); 
			$refreshToken = '/app/soft/auth/refreshToken';
		}
		
		if( !empty($result['error']) && $result['error'] =="Expired token" ){
			$this->errorInfo = 'token过期！';
			$this->code = -101;
			$this->errorData = $refreshToken;
			return false;
		}
		if( !empty($resuxlt['error'])  ){
			$this->errorInfo = 'token错误:'.$result['error'].'！';
			$this->code = -10;
			return false;
	    }
		if($result['jwt']['token_type'] != 'access'){
			$this->errorInfo = 'token类型错误！';
			$this->code = -10;
			return false;
		}
		
		$this->userInfo = $userInfo = $result['info'];
		if ( empty( $userInfo ) ) {
			$this->errorInfo = '登录异常，请重新登录！';
			$this->code = -10;
			return false;
        }

		return true;
    }
	
	//<!--  = 检测是否店铺 =  -->
	private function is_shop(){
		$mode = model('Shop');
		if($this->userInfo['shop_id'] && $this->userInfo['roles_id']){
			$result = $this->shopInfo = $mode->getStaffShopInfo($this->userInfo['id']);
		}else{
			$result = $this->shopInfo = $mode->getUserShopInfo($this->userInfo['id']);
		}
		if(!$result){
			$result = $this->shopInfo = $mode->where('uid',$this->userInfo['id'])->find();
		}
		return $result;
    }
	
	//<!--  = 检测是否存在sql注入 =  -->
	private function is_exist_sql_inject(){
		$pattern='/\binsert\s|\bselect\s|\bupdate\s|\bdelete\s|\bcreate\s|\balter\s|\bdrop\s|(\bexec|\bexecute)[\s\(]|\bsp_|\bxp_|\sinto\s/';
		$param =  strtolower(  json_encode($_REQUEST) );
		return preg_match($pattern,$param) ? true : false;
    }
	
	//<!--  = 检测是否村在特殊符号 =  -->
	private function is_exist_special_symbols(){
		$pregs = '/\*|\#/';
		$param =  strtolower(  json_encode($_REQUEST) );
		return preg_match($pregs,$param) ? true : false;
    }
	

}